package com.test.thread;

import java.awt.*;
import java.util.concurrent.locks.*;

public class LockDemo {
    public static void main(String[] args) {
        Resource resource = new Resource();
        Thread t0 = new Thread(new Producer2(resource));
        Thread t1 = new Thread(new Producer2(resource));
        Thread t2 = new Thread(new Consumer2(resource));
        Thread t3 = new Thread(new Consumer2(resource));


        t0.start();
        t1.start();
        t2.start();
        t3.start();


    }

}

class Resource {
    // 描述资源类
    private String name;
    private int count = 1;
    private boolean flag;
    //将锁单独封装成了一个对象，并提供了对锁的显式操作
    private Lock lock = new ReentrantLock();
    private Condition producer_con = lock.newCondition();
    private Condition consumer_con = lock.newCondition();

    public void set(String name) {
        lock.lock();
        try {

            while (flag) {
                try {
                    //把该线程加入到生产者线程池
                    producer_con.await();
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            this.name = name + "--" + count;
            count++;
            System.out.println(Thread.currentThread().getName() + "...生产者..." + this.name);
            flag = true;
            //只唤醒一个消费者
            consumer_con.signal();
        } finally {
            lock.unlock();
        }
    }

    public void get() {
        lock.lock();
        try {
            while (!flag) {
                try {
                    //把该线程加入到消费者线程池
                    consumer_con.await();
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            System.out.println(Thread.currentThread().getName() + "...消费者..." + this.name);
            flag = false;
            //只唤醒一个生产者
            producer_con.signal();
        } finally {
            lock.unlock();
        }
    }
}

class Producer2 implements Runnable {
    private Resource resource;

    Producer2(Resource resource) {
        this.resource = resource;
    }

    @Override
    public void run() {
        resource.set("面包");
    }
}

class Consumer2 implements Runnable {
    private Resource resource;

    Consumer2(Resource resource) {
        this.resource = resource;
    }

    @Override
    public void run() {
        resource.get();
    }
}

